package com.path.planning.controller;

import com.deductive.common.core.controller.BaseController;
import com.deductive.common.core.domain.AjaxResult;
import com.path.planning.entity.RoutingNetwork;
import com.path.planning.mapper.NetworkDataMapper;
import com.path.planning.mapper.RoutingMapper;
import com.path.planning.util.NetworkDataProcessor;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.io.WKTReader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 路网数据管理控制器
 */
@Api(tags = "路网数据管理")
@RestController
@RequestMapping("/routing/data")
public class NetworkDataController extends BaseController {

    @Autowired
    private NetworkDataMapper networkDataMapper;

    @Autowired
    private RoutingMapper routingMapper;

    @Autowired
    private NetworkDataProcessor dataProcessor;

    private final WKTReader wktReader = new WKTReader();

    /**
     * 导入路网数据
     */
    @ApiOperation("导入路网数据")
    @PostMapping("/import")
    @Transactional
    public AjaxResult importNetworkData(
            @ApiParam("国家代码") @RequestParam String countryCode,
            @ApiParam("路网数据") @RequestBody List<Map<String, Object>> networkData) {
        try {
            // 验证国家代码
            if (!routingMapper.countryExists(countryCode)) {
                return error("不支持的国家代码: " + countryCode);
            }

            // 获取表名
            String tableName = routingMapper.getTableNameByCountryCode(countryCode);
            if (tableName == null) {
                return error("无法获取国家对应的路网表");
            }

            // 验证数据
            if (networkData == null || networkData.isEmpty()) {
                return error("路网数据不能为空");
            }

            // 处理数据
            List<RoutingNetwork> processedData = dataProcessor.processNetworkData(networkData);
            
            if (processedData.isEmpty()) {
                return error("没有有效的数据可以导入");
            }

            // 批量插入数据
            int insertedCount = networkDataMapper.batchInsertNetworks(tableName, processedData);
            
            logger.info("成功导入 {} 条路网数据到国家: {}", insertedCount, countryCode);
            return success("成功导入 " + insertedCount + " 条路网数据");

        } catch (Exception e) {
            logger.error("导入路网数据失败: " + countryCode, e);
            return error("导入失败: " + e.getMessage());
        }
    }

    /**
     * 清空并重新导入路网数据
     */
    @ApiOperation("清空并重新导入路网数据")
    @PostMapping("/import/clear")
    @Transactional
    public AjaxResult clearAndImportNetworkData(
            @ApiParam("国家代码") @RequestParam String countryCode,
            @ApiParam("路网数据") @RequestBody List<Map<String, Object>> networkData) {
        try {
            // 验证国家代码
            if (!routingMapper.countryExists(countryCode)) {
                return error("不支持的国家代码: " + countryCode);
            }

            // 获取表名
            String tableName = routingMapper.getTableNameByCountryCode(countryCode);
            if (tableName == null) {
                return error("无法获取国家对应的路网表");
            }

            // 清空现有数据
            int deletedCount = networkDataMapper.deleteAll(tableName);
            logger.info("清空了 {} 条路网数据", deletedCount);

            // 导入新数据
            return importNetworkData(countryCode, networkData);

        } catch (Exception e) {
            logger.error("清空并重新导入路网数据失败: " + countryCode, e);
            return error("清空并重新导入失败: " + e.getMessage());
        }
    }

    /**
     * 清空路网数据
     */
    @ApiOperation("清空路网数据")
    @PostMapping("/clear")
    @Transactional
    public AjaxResult clearNetworkData(@ApiParam("国家代码") @RequestParam String countryCode) {
        try {
            // 验证国家代码
            if (!routingMapper.countryExists(countryCode)) {
                return error("不支持的国家代码: " + countryCode);
            }

            // 获取表名
            String tableName = routingMapper.getTableNameByCountryCode(countryCode);
            if (tableName == null) {
                return error("无法获取国家对应的路网表");
            }

            // 清空数据
            int deletedCount = networkDataMapper.deleteAll(tableName);
            
            logger.info("清空了 {} 条路网数据", deletedCount);
            return success("成功清空 " + deletedCount + " 条路网数据");

        } catch (Exception e) {
            logger.error("清空路网数据失败: " + countryCode, e);
            return error("清空失败: " + e.getMessage());
        }
    }

    /**
     * 获取数据导入模板
     */
    @ApiOperation("获取数据导入模板")
    @GetMapping("/template")
    public AjaxResult getImportTemplate() {
        try {
            Map<String, Object> template = Map.of(
                "description", "路网数据导入模板",
                "requiredFields", List.of(
                    "name - 道路名称（可选）",
                    "geom - 几何信息 WKT格式（必填）",
                    "length - 道路长度（可选，会自动计算）",
                    "source - 起点节点ID（可选，会自动生成）",
                    "target - 终点节点ID（可选，会自动生成）",
                    "source_point - 起点坐标（可选，会自动生成）",
                    "target_point - 终点坐标（可选，会自动生成）"
                ),
                "example", Map.of(
                    "name", "示例道路",
                    "geom", "LINESTRING(116.4074 39.9042, 121.4737 31.2304)",
                    "length", 1200.5
                ),
                "supportedCountries", routingMapper.getAllCountries()
            );
            
            return success(template);
        } catch (Exception e) {
            logger.error("获取导入模板失败", e);
            return error("获取模板失败: " + e.getMessage());
        }
    }

    /**
     * 验证路网数据
     */
    @ApiOperation("验证路网数据")
    @PostMapping("/validate")
    public AjaxResult validateNetworkData(@RequestBody List<Map<String, Object>> networkData) {
        try {
            List<String> errors = new ArrayList<>();
            List<String> warnings = new ArrayList<>();

            for (int i = 0; i < networkData.size(); i++) {
                Map<String, Object> data = networkData.get(i);
                int lineNumber = i + 1;

                // 检查必填字段
                if (!data.containsKey("geom")) {
                    errors.add("第" + lineNumber + "行: 缺少必填字段 'geom'");
                } else {
                    try {
                        // 验证几何数据格式
                        Geometry geom = wktReader.read(data.get("geom").toString());
                        if (geom == null || !(geom instanceof org.locationtech.jts.geom.LineString)) {
                            errors.add("第" + lineNumber + "行: 几何数据必须是有效的线几何");
                        }
                    } catch (Exception e) {
                        errors.add("第" + lineNumber + "行: 几何数据格式错误: " + e.getMessage());
                    }
                }

                // 检查可选字段
                if (data.containsKey("length")) {
                    try {
                        Double length = Double.valueOf(data.get("length").toString());
                        if (length < 0) {
                            warnings.add("第" + lineNumber + "行: 长度不能为负数");
                        }
                    } catch (NumberFormatException e) {
                        warnings.add("第" + lineNumber + "行: 长度格式错误");
                    }
                }
            }

            Map<String, Object> result = Map.of(
                "valid", errors.isEmpty(),
                "errorCount", errors.size(),
                "warningCount", warnings.size(),
                "errors", errors,
                "warnings", warnings
            );

            return success(result);

        } catch (Exception e) {
            logger.error("验证路网数据失败", e);
            return error("验证失败: " + e.getMessage());
        }
    }
}
